package com.renovate.imtest;


import android.util.Log;

import org.xutils.DbManager;
import org.xutils.db.DbManagerImpl;
import org.xutils.ex.DbException;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Administrator on 2016/8/3.
 */
public class DbUtil {
    private static DbUtil instance = DbUtilsInstance.instance;

    private DbManager mDbManager;
    private DbManager.DaoConfig mdbConfig;

    private final String DB_NAME = "tuo_jian_xutil.db";
    private final int DB_VERSION = 1;

    private ExecutorService msExecutor;

    private DbUtil() {
        mdbConfig = new DbManager.DaoConfig().setDbName(DB_NAME).setDbVersion(DB_VERSION);
        mDbManager = DbManagerImpl.getInstance(mdbConfig);
        msExecutor = Executors.newCachedThreadPool();
    }

    public static DbUtil getInstance() {
        if (instance == null)
            instance = DbUtilsInstance.instance = new DbUtil();
        return instance;
    }

    public DbManager getDbManager() {
        return mDbManager;
    }

    private static class DbUtilsInstance {
        private static DbUtil instance = new DbUtil();
    }

    public void delete(Object entity) {
        if (entity != null) {
            try {
                mDbManager.delete(entity);
            } catch (Exception e) {
                Log.e(TAG(), "delete error:" + e.getMessage());
            }
        } else {
            Log.e(TAG(), "delete NULL");
        }
    }

    public <T> T selectFrist(Class<T> classOfT) {
        T t = null;
        try {
            t = mDbManager.selector(classOfT).findFirst();
        } catch (Exception e) {
            Log.e(TAG(), "select first error:" + e.getMessage());
        }
        if (t == null)
            Log.w(TAG(), "select first is null");
        return t;
    }

    public <T> List<T> selectAll(Class<T> classOfT) {
        List<T> t = null;
        try {
            t = mDbManager.selector(classOfT).findAll();
        } catch (Exception e) {
            Log.e(TAG(), "select all error:" + e.getMessage());
        }
        if (t == null)
            Log.w(TAG(), "select all is null");
        return t;
    }

    public <T> T selectById(Class<T> classOfT, Object id) {
        T t = null;
        try {
            t = mDbManager.findById(classOfT, id);
        } catch (Exception e) {
            Log.e(TAG(), "select by id error:" + e.getMessage());
        }
        if (t == null)
            Log.w(TAG(), "select by id is null");
        return t;
    }

    public <T> List<T> selectByColumn(Class<T> classOfT, String columnName, Object obj) {
        List<T> t = null;
        try {
            t = mDbManager.selector(classOfT).where(columnName, "=", obj).findAll();
        } catch (Exception e) {
            Log.e(TAG(), "select by id error:" + e.getMessage());
        }
        if (t == null)
            Log.w(TAG(), "select by id is null");
        return t;
    }

    public <T> void deleteById(Class<T> classOfT, Object id) {
        try {
            mDbManager.deleteById(classOfT, id);
        } catch (Exception e) {
            Log.e(TAG(), "delete by id error:" + e.getMessage());
        }
    }

    public <T> void clearTable(Class<T> classOfT) {
        try {
            mDbManager.delete(classOfT);
        } catch (Exception e) {
            Log.e(TAG(), "clear table error:" + e.getMessage());
        }
    }

    public <T> void dropTable(Class<T> classOfT) {
        try {
            mDbManager.dropTable(classOfT);
        } catch (Exception e) {
            Log.e(TAG(), "drop table error:" + e.getMessage());
        }
    }

    /**
     * 如果一个对象主键为null则会新增该对象,成功之后【会】对entity的主键进行赋值绑定,否则根据主键去查找更新
     *
     * @param entity
     */
    public void saveOrUpdate(Object entity) {
        try {
            mDbManager.saveOrUpdate(entity);
        } catch (Exception e) {
            Log.e(TAG(), "save or update error:" + e.getMessage());
        }
    }


    /**
     * 保存成功之后【会】对entity的主键进行赋值绑定,并返回保存是否成功
     */
    public void saveBindingId(Object entity) {
        try {
            mDbManager.saveBindingId(entity);
        } catch (Exception e) {
            Log.e(TAG(), "save bingding id error:" + e.getMessage());
        }
    }

    public void replace(Object entity) {
        try {
            mDbManager.replace(entity);
        } catch (Exception e) {
            Log.e(TAG(), "replace error:" + e.getMessage());
        }
    }

    public void update(Object entry, String... columnName) {
        try {
            mDbManager.update(entry, columnName);
        } catch (DbException e) {
            Log.e(TAG(), "update entry error:" + e.getMessage());
        }
    }

    private String TAG() {
        return getClass().getSimpleName();
    }

    public void run(Runnable runnable) {
        msExecutor.execute(runnable);
    }
}
